﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Web.UI;
using Blazing.BusinessObjects.Cms;
using Blazing.BusinessObjects.Tagging;

namespace Blazing.Web.Util
{
    public class RssFeedWriter
    {

        private string _title = "";
        public string Title
        {
            get { return _title; }
            set { _title = value; }
        }

        private string _link = "";
        public string Link
        {
            get { return _link; }
            set { _link = value; }
        }

        private string _description = "";
        public string Description
        {
            get { return _description; }
            set { _description = value; }
        }

        static readonly string DublinCoreNamespace = "http://purl.org/dc/elements/1.1/";
        static readonly string SlashNamespace = "http://purl.org/rss/1.0/modules/slash/";
        static readonly string CommentApiNamespace = "http://wellformedweb.org/CommentAPI/";
        static readonly string TrackbackNamespace = "http://madskills.com/public/xml/rss/module/trackback/";

        public void WriteFeed(XmlWriter writer, IList<Contentpage> list, string rssTitle, string rootUrl, string description, string rssImageUrl)
        {
            _title = rssTitle;
            _link = rootUrl;
            _description = description;

            writer.WriteStartDocument();
            writer.WriteStartElement("rss");
            writer.WriteAttributeString("version", "2.0");
            // Note: No namespace for rss itself!
            writer.WriteAttributeString("xmlns", "dc", null, DublinCoreNamespace);
            writer.WriteAttributeString("xmlns", "slash", null, SlashNamespace);
            writer.WriteAttributeString("xmlns", "wfw", null, CommentApiNamespace);
            writer.WriteAttributeString("xmlns", "trackback", null, TrackbackNamespace);

            writer.WriteStartElement("channel");
            writer.WriteElementString("title", Title);
            writer.WriteElementString("link", Link);
            writer.WriteElementString("description", Description);

            if (!string.IsNullOrEmpty(rssImageUrl))
            {
                writer.WriteStartElement("image");
                writer.WriteElementString("url", rssImageUrl);
                writer.WriteElementString("title", Title);
                writer.WriteElementString("link", Link);
                writer.WriteEndElement(); // image
            }

            // write out items 
            foreach (Contentpage item in list)
            {
                writer.WriteStartElement("item");
                string creator;
                creator = FormatForXml(string.IsNullOrEmpty(item.CreatedBy) ? "admin" : item.CreatedBy);

                writer.WriteElementString("creator", DublinCoreNamespace, creator);
                writer.WriteElementString("title", FormatTitle(item.Name));
                writer.WriteElementString("guid", FormatForXml(rootUrl + item.Url));
                writer.WriteElementString("link", FormatForXml(rootUrl + item.Url));
                writer.WriteElementString("description", item.Content);

                // TODO: Dates are currently stored in UTC in both the xml file provider and the sql server
                // provider. Unfortunately, the object model exposes them in the selected timezone. It should
                // really be up to the consumer of the object model to put them in whichever timezone it requires
                // but that's quite a big job, so in the mean time, we'll let the UI use the selected timezone,
                // and just fix the RSS timezone output to be in UTC (which is what a valid feed should be)
                DateTime dateCreated = item.CreatedDate.ToUniversalTime();
                writer.WriteElementString("pubDate", dateCreated.ToString("r"));

                foreach (TaxonomyTag tag in item.TaxonomyTags)
                {
                    if (tag.Taxonomy.TaxonomyType.Name == "Public")
                    {
                        writer.WriteElementString("category", tag.Tag.Name);
                    }
                }

                writer.WriteElementString("comment", CommentApiNamespace, FormatForXml(item.Url + "#Feedback"));
                writer.WriteElementString("comments", FormatForXml(rootUrl + item.Url + "#Feedback"));
                writer.WriteElementString("comments", SlashNamespace, item.FeedbackItems.Count+"");
                
                //not supported yet...
                //writer.WriteElementString("commentRss", CommentApiNamespace, string.Format("{0}CommentRss.ashx?postID={1}", Globals.UrlStartPath, item.Id));
                //writer.WriteElementString("ping", TrackbackNamespace, string.Format("{0}TrackbackHandler.ashx?postId={1}", Globals.UrlStartPath, item.Id.ToString()));


                writer.WriteEndElement(); // item
            }

            writer.WriteEndElement(); // channel
            writer.WriteEndDocument();
            writer.Flush();
        }


        protected static string FormatTitle(object input)
        {
            string data = "" + input.ToString();      // cast the input to a string
            if (data.Length > 90)
                data = data.Substring(0, 90) + "...";

            return data;
        }


        protected static string FormatForXml(object input)
        {
            string data = input.ToString();      // cast the input to a string

            // replace those characters disallowed in XML documents
            //			data = data.Replace("&", "&amp;");
            //			data = data.Replace("\"", "&quot;");
            //			data = data.Replace("'", "&apos;");
            //			data = data.Replace("<", "&lt;");
            //			data = data.Replace(">", "&gt;");

            return data;
        }
    }
}
